package spectra.ee.web.api.controller;

import java.util.HashMap;
import java.util.Map;

import spectra.base.log.Logger;
import spectra.base.util.StringUtil;
import spectra.ee.web.common.service.AttachWebService;
import spectra.ee.web.common.service.ConfigWebService;
import spectra.ee.web.common.service.SurveyWebService;
import spectra.ee.web.kb.service.KbWebService;
import spectra.ee.web.node.service.NodeWebService;
import spectra.ee.web.qna.service.QnaWebService;

/**
 * 파라메터에 맞게 서비스 객체와 수행할 Method 정보를 제공하는 클래스 <br/>
 * <br/>
 * 1. 새로운 서비스 객체가 추가되는 경우 getService() 함수에 추가한다.<br/>
 * 2. 새로운 함수가 추가되는 경우 생성자에 맵핑 정보를 추가한다.<br/>
 * 3. 넘어오는 파라메터를 맵핑할 model 객체의 Type 이 추가되는 경우  bind() 함수를 수정한다.<br/>
 * @author dhheo
 *
 */
public class ClassMapper implements IParameterMapper
{
	/** Logger객체. */
    private static Logger logger = Logger.getLoggerInstance(ClassMapper.class.getName());
	protected Map commandMapping = null;
	
	public ClassMapper()
	{
		commandMapping = new HashMap();
		/*
		 * 1. 여기에 파라메터로 넘어오는 command 값에 따른 실제 수행할 Method 명을 정의한다.
		 - 내부의 함수명을 숨기는 역활
		 - 내부 함수명이 일관성이 없는 경우 외부 API 함수명을 일관성있게 작성하기 위해 재정의
		 - 외부 API command 명과 내부 함수명이 같은경우는 정의할 필요없음.
		 */
		// node
		addCommandMapping("getNodeList", "selectNodeList");
		addCommandMapping("getChildNodeListToLevel", "selectChildNodeListToLevel");
		// faq
		addCommandMapping("getFaqContentsById", "selectContentsByKbId");
		addCommandMapping("getTopnFaqList", "selectTopnFaq");
		addCommandMapping("getTopKeyword", "selectTopKeyword");
		addCommandMapping("getFaqList","selectFaqList");
		addCommandMapping("searchFaq", "searchKb");
		// qna
		addCommandMapping("getQnaList", "selectQnaList");
		addCommandMapping("getQnaContents", "selectQnaContents");
		addCommandMapping("getQnaContentsList", "selectQnaContentsList");
		addCommandMapping("getQnaNotReadCount", "selectQnaNotReadCount");
		// common
		addCommandMapping("getSurveyListByCondition", "selectSurveyListByCondition");
	}
	
	/**
     * 클라이언트에서 호출할때 command 파라메터 스트링에 따라, 호출할 내부의 실제 method 명 맵핑을 추가한다. <br/>
     * 예를 들어 클라이언트에서 getFaqList 로 호출하고 내부적으로는 selectFaqList method를 호출하면,
     * addCommandMapping("getFaqList", "selectFaqList") 로 맵핑정보를 입력한다.
     * 
     * @param command 클라이언트에서 호출하는 command 파라메터 
     * @param method 서비스 모듈에서 실행될 method 명
     */
    protected final void addCommandMapping(String command, String method)
    {
    	commandMapping.put(command, method);
    }
    
    /**
     * commandMapping 에서 command 스트링에 맵핑된 실제 method 명을 가져온다.
     * 매핑값이 없는 경우는 command 값과 동일한 값을 리턴한다.
     * @param command 클라이언트에서 파라메터로 넘기는 command 스트링
     * @return command 스트링에 맵핑되어 있는 실제 수행할 method 명
     */
	public final String getMethodFromMapping(String command)
	{
		String strMethod = (String)commandMapping.get(command);
    	if (strMethod == null)
    	{
    		strMethod = command;
    	}
    	return strMethod;
	}
	
	/**
     * command 파라메터로 넘어오는 서비스 이름으로 부터, 
     * 서비스 객체를 생성해서 리턴하는 일종의 팩토리 메서드.
     * 
     * @param serviceName 서비스 이름
     * @return 서비스 이름에 해당하는 서비스 모듈 클래스
     */
	public final Object getService(String serviceName) throws Exception
	{
		
		Object objService = null;
    	if (StringUtil.isNotEmpty(serviceName))
    	{
    		
    		if (serviceName.equals("config"))
	    	{
	    		objService = new ConfigWebService();
	    	}
	    	else if (serviceName.equals("search"))
	    	{
	    		objService = new KbWebService();
	    	}
	    	else if (serviceName.equals("faq"))
	    	{
	    		objService = new KbWebService();
	    	} 
	    	else if (serviceName.equals("qna"))
	    	{
	    		objService = new QnaWebService();
	    	}
	    	else if (serviceName.equals("node"))
	    	{
	    		objService = new NodeWebService();
	    	}
	    	else if (serviceName.equals("survey"))
	    	{
	    		objService = new SurveyWebService();
	    	}
	    	else if (serviceName.equals("attach"))
	    	{
	    		objService = new AttachWebService();
	    	}
	    	else
	    	{
	    		logger.error("Illegal Argument Exception : serviceName =" + serviceName);
	    		throw new Exception("Illegal Argument Exception : serviceName =" + serviceName);
	    	}
    	}
    	else
    	{
    		logger.error("Illegal Argument Exception : serviceName =" + serviceName);
    		throw new Exception("Illegal Argument Exception : serviceName =" + serviceName);    		
    	}
    	return objService;
	}
}
